package org.itzixi.filter;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.itzixi.base.BaseInfoProperties;
import org.itzixi.grace.result.ResponseStatusEnum;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

@Component
@Slf4j
public class SecurityFilterToken extends BaseInfoProperties implements GlobalFilter, Ordered {
    @Resource
    private ExcludeUrlProperties excludeUrlProperties;

    //路径匹配规则器
    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.获得当前用户请求路径的url
        String url = exchange.getRequest().getURI().getPath();
        log.info("url={}", url);
        //2.获得所有排除的url list
        List<String> excludeList = excludeUrlProperties.getUrls();
        //3.1校验并且排除excludeList
        if(excludeList != null && !excludeList.isEmpty()){
            for (String excludeUrl : excludeList) {
                //4.如果当前请求url在排除列表中，则放行
                if(antPathMatcher.matchStart(excludeUrl,url)){
                    //放行
                    return chain.filter(exchange);
                }
            }
        }
        //3.2排除static
        String fileStart =excludeUrlProperties.getFileStart();
        if(StringUtils.isNotBlank(fileStart)){
            boolean matchStart=antPathMatcher.matchStart(fileStart,url);
            if(matchStart){
                return chain.filter(exchange);
            }
        }
        //4.代码到达此处说明被拦截，需要校验
        log.info("被拦截的请求url:[{}]",url);

        //5.从header中获取用户id和用户token
        HttpHeaders headers = exchange.getRequest().getHeaders();
        String userId = headers.getFirst(HEADER_USER_ID);
        String userToken = headers.getFirst(HEADER_USER_TOKEN);
        log.info("userId={}, userToken={}", userId, userToken);
        //6.判断header中是否有token，对用户请求进行判断拦截
        if(StringUtils.isNotBlank(userId)&&StringUtils.isNotBlank(userToken)){
            //限制只能单设备登录
//            String redisToken = redis.get(REDIS_USER_TOKEN + ":" + userId);
//            if(redisToken.equals(userToken)){
//                return chain.filter(exchange);
//            }
            //允许多设备登录
            String userIdRedis = redis.get(REDIS_USER_TOKEN + ":" + userToken);
            if(userId.equals(userIdRedis)){
                return chain.filter(exchange);
            }
        }
        //默认不放行
        return RenderErrorUtils.display(exchange, ResponseStatusEnum.UN_LOGIN);
    }

    // 过滤器的优先级，数字越小，优先级越高
    @Override
    public int getOrder() {
        return 0;
    }


}
